package com.ssy.lingxi.member.merchant.serviceimpl.web;

import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberOrderCommentVO;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.MemberTradeCommentSubmitDetailVO;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.MemberOrderCommentDO;
import com.ssy.lingxi.member.merchant.entity.MemberOrderProductCommentDO;
import com.ssy.lingxi.member.merchant.model.constant.MemberStringEnum;
import com.ssy.lingxi.member.merchant.model.constant.MemberTradeTypeEnum;
import com.ssy.lingxi.member.merchant.model.vo.comment.request.MemberTradeCommentSubmitVO;
import com.ssy.lingxi.member.merchant.repository.MemberOrderCommentRepository;
import com.ssy.lingxi.member.merchant.repository.MemberOrderProductCommentRepository;
import com.ssy.lingxi.member.merchant.service.feign.IPlatformManageFeignService;
import com.ssy.lingxi.member.merchant.service.feign.IScheduleFeignService;
import com.ssy.lingxi.member.merchant.service.web.IMemberCommentScheduleService;
import com.ssy.lingxi.member.merchant.service.web.IMemberCommentService;
import com.ssy.lingxi.platform.manage.api.model.vo.parameter.PlatformParameterManageVO;
import com.ssy.lingxi.scheduler.api.model.ScheduleTaskCallbackVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员评论服务接口实现类
 *
 * @author 姚梓聪
 * @version 2.0.0
 * @date 2020-10-23
 */
@Service
public class MemberCommentScheduleServiceImpl implements IMemberCommentScheduleService {

    private static final Logger log = LoggerFactory.getLogger(MemberCommentScheduleServiceImpl.class);

    @Resource
    private IPlatformManageFeignService platformManageFeignService;

    @Resource
    private MemberOrderCommentRepository memberOrderCommentRepository;

    @Resource
    private MemberOrderProductCommentRepository memberOrderProductCommentRepository;

    @Resource
    private IMemberCommentService memberCommentService;

    @Resource
    private IScheduleFeignService scheduleFeignService;

    @Async
    public void asyncOrderAutoComment(MemberOrderCommentVO memberOrderCommentVO) {
        Wrapper<PlatformParameterManageVO> parameterManageWrapper = platformManageFeignService.parameterManageDetails(ServiceConfig.ORDER_AUTO_COMMENT_PARAMETER_CODE);
        if (ResponseCode.SUCCESS.getCode() != parameterManageWrapper.getCode()) {
            log.error("设置定时评价, 查询自动评价时间失败: {}", parameterManageWrapper.getMessage());
            return;
        }

        PlatformParameterManageVO parameter = parameterManageWrapper.getData();
        if (Objects.isNull(parameter)
                || EnableDisableStatus.DISABLE.getCode().equals(parameter.getState())
                || parameter.getParameterValue() < 0
        ) {
            log.error("自动评价订单, 查询自动评价时间有误");
            return;
        }

        // 需要执行的数据
        List<Long> dataIds = Collections.singletonList(memberOrderCommentVO.getId());
        // 保留两位精度, 最小值24(小时) * 0.01 = 0.24(小时), 即14.4(分钟)
        BigDecimal day = BigDecimal.valueOf(parameter.getParameterValue()).setScale(2, RoundingMode.HALF_UP);
        if (BigDecimal.ZERO.compareTo(day) >= 0) {
            // 如果设置精度, 导致值太小或为0,则取最小时间
            day = BigDecimal.valueOf(0.01);
        }
        long commentTimeMillis = day.multiply(BigDecimal.valueOf(Constants.DAY_TO_MILLISECONDS)).longValue();
        long executeTime = System.currentTimeMillis() + commentTimeMillis;

        // 采购评价
        HashMap<String, Object> buyerTaskAttributes = new HashMap<>();
        buyerTaskAttributes.put(ServiceConfig.ORDER_COMMENT_ATTR, MemberTradeTypeEnum.BUYER.getTypeEnum());
        Wrapper<Long> buyerWrapper = scheduleFeignService.createScheduleTask(dataIds, executeTime, ServiceConfig.ORDER_COMMENT_CALLBACK_URL,
                buyerTaskAttributes, memberOrderCommentVO.getBuyerMemberId(), memberOrderCommentVO.getBuyerRoleId());
        if (buyerWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("采购自动评价调用定时服务失败:{}", buyerWrapper.getMessage());
        }

        // 供应商评价(延迟1秒执行)
        HashMap<String, Object> vendorTaskAttributes = new HashMap<>();
        vendorTaskAttributes.put(ServiceConfig.ORDER_COMMENT_ATTR, MemberTradeTypeEnum.SELLER.getTypeEnum());
        Wrapper<Long> vendorWrapper = scheduleFeignService.createScheduleTask(dataIds, executeTime + 1000, ServiceConfig.ORDER_COMMENT_CALLBACK_URL,
                vendorTaskAttributes, memberOrderCommentVO.getVendorMemberId(), memberOrderCommentVO.getVendorRoleId());
        if (buyerWrapper.getCode() != ResponseCode.SUCCESS.getCode()) {
            log.error("供应自动评价调用定时服务失败:{}", vendorWrapper.getMessage());
        }
    }

    @Override
    public Wrapper<Void> autoCommentCallback(ScheduleTaskCallbackVO callbackVO) {
        Map<String, Object> taskAttributes = callbackVO.getTaskAttributes();
        if (Objects.isNull(taskAttributes) || !taskAttributes.containsKey(ServiceConfig.ORDER_COMMENT_ATTR)) {
            String errorMsg = "taskAttributes为空, 或自定义属性无值";
            log.error("定时任务回调错误: {}", errorMsg);
            return Wrapper.fail(errorMsg);
        }
        if (CollectionUtils.isEmpty(callbackVO.getDataIds())) {
            String errorMsg = "dataIds为空";
            log.error("定时任务回调错误: {}", errorMsg);
            return Wrapper.fail(errorMsg);
        }

        Long orderId = callbackVO.getDataIds().get(0);
        MemberOrderCommentDO memberOrderCommentDO = memberOrderCommentRepository.findById(orderId).orElse(null);
        if (Objects.isNull(memberOrderCommentDO)) {
            log.error("查询待评价订单失败, orderId: {}", orderId);
            return Wrapper.fail("查询待评价订单失败");
        }

        // 查询订单商品
        List<MemberOrderProductCommentDO> orderProductCommentDOList = memberOrderProductCommentRepository.findAllByOrderId(orderId);

        if (MemberTradeTypeEnum.BUYER.getTypeEnum().equals(taskAttributes.get(ServiceConfig.ORDER_COMMENT_ATTR))) {
            // 待评价自动评价内容
            List<MemberTradeCommentSubmitDetailVO> commentSubmitDetailVOList = orderProductCommentDOList.stream().
                    filter(e -> EnableDisableStatus.DISABLE.getCode().equals(e.getBuyerCommentStatus()))
                    .map(e -> {
                        MemberTradeCommentSubmitDetailVO commentSubmitDetailVO = new MemberTradeCommentSubmitDetailVO();
                        commentSubmitDetailVO.setOrderProductId(e.getId());
                        commentSubmitDetailVO.setStar(5);
                        commentSubmitDetailVO.setComment(MemberStringEnum.AUTO_COMMENT.getName());
                        return commentSubmitDetailVO;
                    }).collect(Collectors.toList());

            // 提价评价
            MemberTradeCommentSubmitVO commentSubmitVO = new MemberTradeCommentSubmitVO();
            commentSubmitVO.setOrderId(orderId);
            commentSubmitVO.setCommentSubmitDetailList(commentSubmitDetailVOList);
            memberCommentService.submitAutoMemberTradeComment(MemberTradeTypeEnum.BUYER, memberOrderCommentDO, commentSubmitVO);

        } else if (MemberTradeTypeEnum.SELLER.getTypeEnum().equals(taskAttributes.get(ServiceConfig.ORDER_COMMENT_ATTR))) {
            // 待评价自动评价内容
            List<MemberTradeCommentSubmitDetailVO> commentSubmitDetailVOList = orderProductCommentDOList.stream().
                    filter(e -> EnableDisableStatus.DISABLE.getCode().equals(e.getVendorCommentStatus()))
                    .map(e -> {
                        MemberTradeCommentSubmitDetailVO commentSubmitDetailVO = new MemberTradeCommentSubmitDetailVO();
                        commentSubmitDetailVO.setOrderProductId(e.getId());
                        commentSubmitDetailVO.setStar(5);
                        commentSubmitDetailVO.setComment(MemberStringEnum.AUTO_COMMENT.getName());
                        return commentSubmitDetailVO;
                    }).collect(Collectors.toList());

            // 提价评价
            MemberTradeCommentSubmitVO commentSubmitVO = new MemberTradeCommentSubmitVO();
            commentSubmitVO.setOrderId(orderId);
            commentSubmitVO.setCommentSubmitDetailList(commentSubmitDetailVOList);
            memberCommentService.submitAutoMemberTradeComment(MemberTradeTypeEnum.SELLER, memberOrderCommentDO, commentSubmitVO);
        } else {
            return Wrapper.fail("附加属性参数有误");
        }

        return Wrapper.success();
    }
}
